/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.excesys.exsecs.access.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.excesys.exsecs.access.dto.AccessSupplierDTO;
import com.excesys.exsecs.access.entity.AccessSupplier;
import com.excesys.exsecs.access.mapper.AccessSupplierMapper;
import com.excesys.exsecs.access.service.AccessSupplierService;
import com.excesys.exsecs.access.vo.AccessSupplierExcelVO;
import com.excesys.exsecs.common.core.util.R;
import com.excesys.exsecs.common.excel.vo.ErrorMessage;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.text.DecimalFormat;
import java.text.Format;
import java.text.ParseException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 供应商信息表
 *
 * @author lxc
 * @date 2024-05-06 17:44:39
 */
@Service
public class AccessSupplierServiceImpl extends ServiceImpl<AccessSupplierMapper, AccessSupplier>
		implements AccessSupplierService {

	@Override
	public LambdaQueryWrapper buildQueryWrapper(AccessSupplierDTO supplierDTO) {
		// 定义查询条件
		LambdaQueryWrapper<AccessSupplierDTO> wrapper = Wrappers.<AccessSupplierDTO>lambdaQuery()
				.like(StrUtil.isNotBlank(supplierDTO.getSupplierName()), AccessSupplierDTO::getSupplierName,
						supplierDTO.getSupplierName())
				.eq(StrUtil.isNotBlank(supplierDTO.getSupplierType()), AccessSupplierDTO::getSupplierType,
						supplierDTO.getSupplierType())
				.eq(StrUtil.isNotBlank(supplierDTO.getSupplierId()), AccessSupplierDTO::getSupplierId,
						supplierDTO.getSupplierId())
				.eq(StrUtil.isNotBlank(supplierDTO.getSupplierCode()), AccessSupplierDTO::getSupplierCode,
						supplierDTO.getSupplierCode())
				.orderByDesc(AccessSupplierDTO::getCreateTime);

		if (ArrayUtil.isNotEmpty(supplierDTO.getQueryTime())) {
			// 根据时间轴查询 创建时间
			wrapper.ge(AccessSupplierDTO::getCreateTime, supplierDTO.getQueryTime()[0])
					.le(AccessSupplierDTO::getCreateTime, supplierDTO.getQueryTime()[1]);
		}
		return wrapper;
	}

	@Override
	public Page<AccessSupplier> getSupplierByPage(Page page, AccessSupplierDTO supplierDTO) {
		return baseMapper.selectPage(page, buildQueryWrapper(supplierDTO));
	}

	/**
	 * @description: TODO 自动生成唯一编码 @param @return @throws @author yuan quan @date 2023/3/7
	 * 14:28
	 */
	@Override
	public synchronized String getNum() throws ParseException {
		// 供应商编号编码(7位)=GYS+流水号（4位）
		String num = "0000";
		String code = "GYS";
		String seqNum = "";
		List<AccessSupplier> suppliers = baseMapper.selectList(
				Wrappers.lambdaQuery(AccessSupplier.class).orderByDesc(AccessSupplier::getSupplierCode));
		if (suppliers.size() > 0) {
			// 以最大的编号数自增后的结果作为编码
			String snum = suppliers.get(0).getSupplierCode().replace("GYS", "");
			Format f = new DecimalFormat("0000");
			Long ij = (Long) f.parseObject(snum);
			ij = ij + 1;
			num = f.format(ij);
			seqNum = code + num;
		}
		else {
			seqNum = code + num;
		}
		return seqNum;
	}

	@Override
	public List<AccessSupplierExcelVO> listAccessSupplier(AccessSupplierDTO supplierDTO) {
		List<AccessSupplier> suppliers = this.list(buildQueryWrapper(supplierDTO));
		// 转换成execl 对象输出
		return suppliers.stream().map(supplier -> {
			AccessSupplierExcelVO supplierExcelVO = new AccessSupplierExcelVO();
			BeanUtil.copyProperties(supplier, supplierExcelVO);
			// bamSSubareaExcelVO.setSubareaCoords(subarea.getSubareaCoords());
			return supplierExcelVO;
		}).collect(Collectors.toList());
	}

	@Override
	public R importAccessSupplier(List<AccessSupplierExcelVO> excelVOList, BindingResult bindingResult) {
		// 通用校验获取失败的数据
		List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
		// 个性化校验逻辑
		List<AccessSupplier> suppliers = this.list();

		int sucess = 0;
		int fail = 0;
		// 执行数据插入操作 组装 RoleDto
		for (AccessSupplierExcelVO excel : excelVOList) {

			Set<String> errorMsg = new HashSet<>();

			boolean existSSubarea = suppliers.stream()
					.anyMatch(subarea -> excel.getSupplierCode().equals(subarea.getSupplierCode()));
			if (existSSubarea) {
				errorMsg.add("供应商编码：" + excel.getSupplierCode() + "已经存在。");
			}
			// 数据合法情况
			if (CollUtil.isEmpty(errorMsg)) {
			}
			else {
				// 数据不合法情况
				errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
			}
			int num = insertAccessSupplier(excel);
			if (num == 1) {
				fail++;
			}
			else {
				sucess++;
			}
		}
		if (CollUtil.isNotEmpty(errorMessageList)) {
			return R.failed(errorMessageList);
		}
		return R.ok(sucess, "成功导入数量" + sucess + "。" + "存在" + fail + "重复");
	}

	private int insertAccessSupplier(AccessSupplierExcelVO excel) {
		AccessSupplier supplier = new AccessSupplier();
		List<AccessSupplier> suppliers = baseMapper.selectList(Wrappers.<AccessSupplier>lambdaQuery()
				.eq(AccessSupplier::getSupplierCode, excel.getSupplierCode()));
		if (suppliers.size() <= 0) {
			supplier.setRemark(excel.getRemark());
			supplier.setSupplierAddress(excel.getSupplierAddress());
			supplier.setSupplierCode(excel.getSupplierCode());
			supplier.setSupplierName(excel.getSupplierName());
			supplier.setSupplierPhone(excel.getSupplierPhone());
			supplier.setSupplierType(excel.getSupplierType());
			this.save(supplier);
			return 0;
		}
		else {
			return 1;
		}
	}

}
